from rest_framework import serializers

from apps.goods.models import SKU,GoodsCategory,SPU,SPUSpecification,SpecificationOption
from apps.goods.models import SKUSpecification


class GoodsCategorySerializer(serializers.ModelSerializer):

    class Meta:
        model = GoodsCategory
        # fields = '__all__'
        fields = ['id','name']

class SPUSerializer(serializers.ModelSerializer):

    class Meta:
        model = SPU
        # fields = '__all__'
        fields = ['id', 'name']


class SPUSpecifationOptionSerializer(serializers.ModelSerializer):

    class Meta:
        model = SpecificationOption
        # fields = '__all__'
        fields = ['id','value']


class SPUSpecifationSerializer(serializers.ModelSerializer):

    options = SPUSpecifationOptionSerializer(read_only=True,many=True)
    class Meta:
        model = SPUSpecification
        fields = '__all__'

 # sku对应的规格序列化器，因为外键是SKU,保存时需要向规格信息传递信息
class SKUSpecificationSerializer(serializers.ModelSerializer):

    spec_id = serializers.IntegerField()   #两个外键字段，需要自己写字段
    option_id = serializers.IntegerField()
    class Meta:
        model = SKUSpecification
        fields = ('spec_id','option_id')

#展示SKU列表，新增数据重写方法
class SKUSerializer(serializers.ModelSerializer):
    category = serializers.StringRelatedField(read_only=True)
    spu = serializers.StringRelatedField(read_only=True)

    category_id = serializers.IntegerField()
    spu_id = serializers.IntegerField()

    specs = SKUSpecificationSerializer(many=True)  #接收了字典列表

    class Meta:
        model = SKU
        fields = '__all__'

    #create方法不支持保存nested field嵌套数据（字典列表）
    def create(self, validated_data):
        #序列化器中的属性，可以通过self.context获得一个字典。里面储存request,view,format
        # data = self.context['request'].data
        # specs = data.get('specs')
        # if "specs" in validated_data:
        #     del validated_data['specs']

        specs = validated_data.pop('specs')   #取出列表字典，并删除
        from django.db import transaction

        with transaction.atomic():
            save_point = transaction.savepoint()
            try:
                sku = SKU.objects.create(**validated_data)
                for item in specs:
                    # SKUSpecification.objects.create(
                    #     sku = sku,                    #遍历保存列表字典
                    #     spec_id=item.get('spec_id'),
                    #     option_id = item.get('option_id')
                    # )
                    SKUSpecification.objects.create(sku=sku,**item)
            except Exception:
                transaction.savepoint_rollback(save_point)
                raise serializers.ValidationError('保存失败')
            else:
                transaction.savepoint_commit(save_point)
                #生成HTML静态页面,异步任务
                #访问地址http://127.0.0.1:8000/static/detail/20.html
                #celery报错保存一个默认图片
                sku.default_image = 'group1/M00/00/03/wKjH6V5J11GABZbBAAFxUq5femA2547894'
                sku.save()
                from celery_tasks.html.tasks import generate_static_sku_detail_html
                generate_static_sku_detail_html.delay(sku.id)

                return sku

    def update(self, instance, validated_data):
        specs = validated_data.pop('specs')
        super().update(instance, validated_data)

        for item in specs:
            SKUSpecification.objects.filter(
                sku=instance.id,
                spec_id=item['spec_id']

            ).update(option_id = item['option_id'])

        from celery_tasks.html.tasks import generate_static_sku_detail_html
        pk = self.context['view'].kwargs.get('pk')
        generate_static_sku_detail_html(pk)

        return instance